package com.scau.meetingbook.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.scau.meetingbook.dto.MeetingRoomDTO;
import com.scau.meetingbook.dto.MeetingRoomsDTO;
import com.scau.meetingbook.mapper.RoomEquipmentMapper;
import com.scau.meetingbook.mapper.RoomReservationsMapper;
import com.scau.meetingbook.pojo.MeetingRooms;
import com.scau.meetingbook.mapper.MeetingRoomsMapper;
import com.scau.meetingbook.pojo.RoomEquipment;
import com.scau.meetingbook.pojo.RoomReservations;
import com.scau.meetingbook.service.MeetingRoomsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.scau.meetingbook.utils.TimeConverter;
import com.scau.meetingbook.vo.ResultVO;
import lombok.val;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;


import java.text.ParseException;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class MeetingRoomsServiceImpl extends ServiceImpl<MeetingRoomsMapper, MeetingRooms> implements MeetingRoomsService {

    @Autowired
    private MeetingRoomsMapper meetingRoomsMapper;

    @Autowired
    private RoomEquipmentMapper roomEquipmentMapper;

    @Autowired
    private RoomReservationsMapper roomReservationsMapper;


    @Override
    public ResultVO<MeetingRooms> getMeetingRoomsById(Integer id) throws Exception {
        return ResultVO.success(null, meetingRoomsMapper.selectById(id));
    }

    @Transactional
    @Override
    public ResultVO<List<MeetingRoomsDTO>> getMeetingRooms(Date date, String startTime, String endTime, Integer personNum, String type, ArrayList<Integer> equipmentIds) throws ParseException {

        // 将字符串转换为 Date 对象
        LocalTime start = LocalTime.parse(startTime);
        LocalTime end = LocalTime.parse(endTime);

        //查询人数相符的会议室且状态不为维修
        QueryWrapper<MeetingRooms> ne = new QueryWrapper<MeetingRooms>().ge("max_capacity", personNum).ne("status", "maintenance");
        if (type != null && !type.isEmpty()) {
            ne.eq("type", type);
        }
        List<MeetingRooms> maxCapacity = this.baseMapper.selectList(ne);

        //查询时间相符的会议室
        List<MeetingRoomsDTO> meetingRooms = maxCapacity.stream().map(item -> {
            List<RoomReservations> roomId = roomReservationsMapper.selectList(new QueryWrapper<RoomReservations>().eq("room_id", item.getRoomId()));
            boolean flag = true;
            for (RoomReservations roomReservations : roomId) {
                if (roomReservations.getReservationDate().equals(date)) {
                    flag = false;
                    // 将 Date 转换为 LocalTime（使用系统默认时区）
                    LocalTime StartTime = roomReservations.getStartTime().toInstant()
                            .atZone(ZoneId.systemDefault())
                            .toLocalTime();
                    LocalTime EndTime = roomReservations.getEndTime().toInstant()
                            .atZone(ZoneId.systemDefault())
                            .toLocalTime();
                    if (!StartTime.isBefore(end) || !EndTime.isAfter(start)) {
                        return getMeetRoomDTO(item);
                    } else if (roomReservations.getReservationStatus().equals("cancelled")) {
                        return getMeetRoomDTO(item);
                    } else {
                        return null;
                    }
                }
            }
            if (flag) {
                return getMeetRoomDTO(item);
            } else {
                return null;
            }
        }).collect(Collectors.toList());

        //添加每个会议室所拥有的设备
        meetingRooms.forEach(item -> {
            if (item != null) {
                List<RoomEquipment> roomId = roomEquipmentMapper.selectList(new QueryWrapper<RoomEquipment>().eq("room_id", item.getRoomId()));
                item.setRoomEquipments(roomId);
            }
        });

        //查询多媒体设备相符的会议室
        if (equipmentIds != null && !equipmentIds.isEmpty()) {
            List<MeetingRoomsDTO> collect = meetingRooms.stream().map(item -> {
                if (item != null) {
                    List<RoomEquipment> roomId = roomEquipmentMapper.selectList(new QueryWrapper<RoomEquipment>().eq("room_id", item.getRoomId()));
                    boolean a = true;
                    for (Integer equipmentId : equipmentIds) {
                        boolean b = false;
                        for (RoomEquipment roomEquipment : roomId) {
                            if (roomEquipment.getEquipmentId().equals(equipmentId)) {
                                b = true;
                                break;
                            }
                        }
                        if (!b) {
                            a = false;
                            break;
                        }
                    }
                    if (a) {
                        return item;
                    }
                }
                return null;
            }).collect(Collectors.toList());
            return ResultVO.success(null, collect);
        } else {
            return ResultVO.success(null, meetingRooms);
        }
    }

    private MeetingRoomsDTO getMeetRoomDTO(MeetingRooms item) {
        MeetingRoomsDTO meetingRoomsDTO = new MeetingRoomsDTO();
        meetingRoomsDTO.setRoomId(item.getRoomId());
        meetingRoomsDTO.setName(item.getName());
        meetingRoomsDTO.setType(item.getType());
        meetingRoomsDTO.setMaxCapacity(item.getMaxCapacity());
        meetingRoomsDTO.setHourlyRentalPrice(item.getHourlyRentalPrice());
        meetingRoomsDTO.setStatus(item.getStatus());
        return meetingRoomsDTO;
    }

    @Override
    public ResultVO<List<MeetingRooms>> getAllMeetingRoomsStatus() {
        List<MeetingRooms> meetingRooms = meetingRoomsMapper.selectList(null);
        return ResultVO.success("成功", meetingRooms);
    }

    @Override
    public ResultVO changeMeetingRoomsStatus(Integer roomId, String status) {
        MeetingRooms meetingRooms = meetingRoomsMapper.selectById(roomId);
        if (meetingRooms == null) {
            return ResultVO.fail("会议室不存在");
        }
        meetingRooms.setStatus(status);
        meetingRoomsMapper.updateById(meetingRooms);
        return ResultVO.success("成功");
    }

    // 新增会议室（包含设备）
    @Transactional
    @Override
    public ResultVO insertMeetingRooms(MeetingRoomDTO meetingRoomDTO) {
        // 假设 TimeConverter 是一个已经定义好的类，并具有无参构造函数
        TimeConverter timeConverter = new TimeConverter(); // 实例化对象，避免空指针异常
        Date availableStartTime = timeConverter.convertStringToDate("08:00:00");
        Date availableEndTime = timeConverter.convertStringToDate("22:00:00");

        try {
            // 1. 插入会议室基本信息
            MeetingRooms meetingRoom = convertToMeetingRooms(meetingRoomDTO);
            int result = meetingRoomsMapper.insert(meetingRoom);
            if (result <= 0) {
                return ResultVO.fail("会议室创建失败");
            }

            // 2. 获取新生成的room_id
            Integer roomId = meetingRoom.getRoomId();
            meetingRoom.setAvailableStartTime(availableStartTime);
            meetingRoom.setAvailableEndTime(availableEndTime);
            meetingRoom.setCreateBy(1);
            meetingRoom.setCreateTime(new Date());

            // 3. 插入设备信息
            List<Integer> equipmentIds = meetingRoomDTO.getEquipmentIds();
            if (equipmentIds != null && !equipmentIds.isEmpty()) {
                for (Integer equipmentId : equipmentIds) {
                    RoomEquipment equipment = new RoomEquipment();
                    equipment.setRoomId(roomId);
                    equipment.setEquipmentId(equipmentId);

                    // 根据设备ID设置设备名称
                    switch (equipmentId) {
                        case 1:
                            equipment.setEquipmentName("投影");
                            break;
                        case 2:
                            equipment.setEquipmentName("音响");
                            break;
                        case 3:
                            equipment.setEquipmentName("网络");
                            break;
                        default:
                            throw new IllegalArgumentException("无效的设备ID: " + equipmentId);
                    }

                    roomEquipmentMapper.insert(equipment);
                }
            }
            return ResultVO.success("会议室创建成功");
        } catch (Exception e) {
            return ResultVO.fail("创建失败: " + e.getMessage());
        }
    }

    // 修改会议室（包含设备）
    @Transactional
    @Override
    public ResultVO updateMeetingRoomsById(MeetingRoomDTO meetingRoomDTO) {
        try {
            Integer roomId = meetingRoomDTO.getRoomId();
            if (roomId == null) {
                return ResultVO.fail("会议室ID不能为空");
            }

            // 1. 更新会议室基本信息
            MeetingRooms meetingRoom = convertToMeetingRooms(meetingRoomDTO);
            meetingRoom.setUpdateBy(1);
            meetingRoom.setUpdateTime(new Date());
            int updateResult = meetingRoomsMapper.updateById(meetingRoom);
            if (updateResult <= 0) {
                return ResultVO.fail("会议室信息更新失败");
            }

            // 2. 删除原有设备
            QueryWrapper<RoomEquipment> deleteWrapper = new QueryWrapper<>();
            deleteWrapper.eq("room_id", roomId);
            roomEquipmentMapper.delete(deleteWrapper);

            // 3. 插入新设备
            List<Integer> equipmentIds = meetingRoomDTO.getEquipmentIds();
            if (equipmentIds != null && !equipmentIds.isEmpty()) {
                for (Integer equipmentId : equipmentIds) {
                    RoomEquipment equipment = new RoomEquipment();
                    equipment.setRoomId(roomId);
                    equipment.setEquipmentId(equipmentId);

                    // 根据设备ID设置设备名称
                    switch (equipmentId) {
                        case 1:
                            equipment.setEquipmentName("投影");
                            break;
                        case 2:
                            equipment.setEquipmentName("音响");
                            break;
                        case 3:
                            equipment.setEquipmentName("网络");
                            break;
                        default:
                            throw new IllegalArgumentException("无效的设备ID: " + equipmentId);
                    }

                    roomEquipmentMapper.insert(equipment);
                }
            }
            return ResultVO.success("会议室更新成功");
        } catch (Exception e) {
            return ResultVO.fail("更新失败: " + e.getMessage());
        }
    }

    // 删除会议室
    @Transactional
    @Override
    public ResultVO deleteMeetingRoomsById(Integer id) {
        try {
            // 1. 检查会议室是否存在未完成的预定
            QueryWrapper<RoomReservations> reservationWrapper = new QueryWrapper<>();
            reservationWrapper.eq("room_id", id)
                    .in("reservation_status", "pending", "confirmed");

            int reservationCount = roomReservationsMapper.selectCount(reservationWrapper);
            if (reservationCount > 0) {
                return ResultVO.fail("会议室存在未完成的预定，无法删除");
            }

            // 2. 删除设备信息
            QueryWrapper<RoomEquipment> equipmentWrapper = new QueryWrapper<>();
            equipmentWrapper.eq("room_id", id);
            roomEquipmentMapper.delete(equipmentWrapper);

            // 3. 删除会议室
            int deleteResult = meetingRoomsMapper.deleteById(id);
            if (deleteResult <= 0) {
                return ResultVO.fail("会议室删除失败");
            }

            return ResultVO.success("会议室删除成功");
        } catch (Exception e) {
            return ResultVO.fail("删除失败: " + e.getMessage());
        }
    }

    // 转换DTO到实体
    private MeetingRooms convertToMeetingRooms(MeetingRoomDTO dto) {
        MeetingRooms meetingRoom = new MeetingRooms();
        meetingRoom.setRoomId(dto.getRoomId());
        meetingRoom.setName(dto.getName());
        meetingRoom.setType(dto.getType());
        meetingRoom.setMaxCapacity(dto.getMaxCapacity());
        meetingRoom.setHourlyRentalPrice(dto.getHourlyRentalPrice());
        meetingRoom.setAvailableStartTime(dto.getAvailableStartTime());
        meetingRoom.setAvailableEndTime(dto.getAvailableEndTime());
        meetingRoom.setStatus(dto.getStatus());
        meetingRoom.setCreateBy(dto.getCreateBy());
        meetingRoom.setCreateTime(dto.getCreateTime());
        meetingRoom.setUpdateBy(dto.getUpdateBy());
        meetingRoom.setUpdateTime(dto.getUpdateTime());
        return meetingRoom;
    }

    @Override
    public ResultVO<List<MeetingRoomsDTO>> getAllMeetingRooms() {
        List<MeetingRoomsDTO> meetingRoomsDTOs = meetingRoomsMapper.selectAllMeetingRooms();
        return ResultVO.success("成功", meetingRoomsDTOs);
    }
}